package com.laker.monitor.agent.bytebuddy.interceptor;

import com.laker.monitor.agent.bytebuddy.dto.TreeView;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;

import java.lang.reflect.Method;
import java.util.concurrent.Callable;

/**
 * 链路耗时统计代理
 *
 * @author laker
 */
public class TraceInterceptor {
    static ThreadLocal<TreeView> local = ThreadLocal
            .withInitial(() -> new TreeView(true, "[" + Thread.currentThread().getName() + "]-laker.trace-[start]---"));
    static ThreadLocal<Long> localLong = ThreadLocal.withInitial(() -> 0L);

    @RuntimeType
    public static Object intercept(@Origin Method method,
                                   @SuperCall Callable<?> callable) throws Exception {
        String data = "[" + Thread.currentThread().getName() + "] " + method.getDeclaringClass().getName() + "." + method.getName();
        local.get().begin(data);
        long now = localLong.get();
        localLong.set(++now);
        try {
            // 原有函数执行
            return callable.call();
        } finally {
            local.get().end();
            now = localLong.get();
            localLong.set(--now);
            if (localLong.get() == 0) {
                System.out.println(local.get().draw() + "`---[" + Thread.currentThread().getName() + "]-laker.trace-[end]---");
                localLong.remove();
                local.remove();
            }
        }
    }
}